package fatworm.storage.buffer;

import fatworm.server.*;
import fatworm.storage.file.*;

/**
 * An individual buffer. A buffer wraps a page and stores information about its
 * status, such as the disk block associated with the page, the number of times
 * the block has been pinned, whether the contents of the page have been
 * modified, and if so, the id of the modifying transaction and the LSN of the
 * corresponding log record.
 * 
 * @author Edward Sciore
 */
public class Buffer
{
    private Page contents = new Page();
    private Block blk = null;
    private int pins = 0;
    private int modifiedBy = -1; // negative means not modified
    private int lsn = -1;

    public Buffer()
    {
    }
    public int getInt(int offset)
    {
        return contents.getInt(offset);
    }
    public byte[] getBytes(int offset, int len)
    {
        return contents.getBytes(offset, len);
    }
    public void setInt(int offset, int val, int txnum, int lsn)
    {
        modifiedBy = txnum;
        if (lsn >= 0)
            this.lsn = lsn;
        contents.setInt(offset, val);
    }
    public void setBytes(int offset, byte[] val, int txnum, int lsn)
    {
        modifiedBy = txnum;
        if (lsn >= 0)
            this.lsn = lsn;
        contents.setBytes(offset, val);
    }
    public Block block()
    {
        return blk;
    }
    void flush()
    {
        if (modifiedBy >= 0)
        {
            Fatworm.logMgr.flush(lsn);
            contents.write(blk);
            modifiedBy = -1;
        }
    }
    void pin()
    {
        pins++;
    }
    void unpin()
    {
        pins--;
    }
    boolean isPinned()
    {
        return pins > 0;
    }
    boolean isModifiedBy(int txnum)
    {
        return txnum == modifiedBy;
    }
    void assignToBlock(Block b)
    {
        flush();
        blk = b;
        contents.read(blk);
        pins = 0;
    }
    void assignToNew(String filename, PageFormatter fmtr)
    {
        flush();
        fmtr.format(contents);
        blk = contents.append(filename);
        pins = 0;
    }
}